#ifndef LOADER_H
#define LOADER_H

#include <QObject>
#include <QFile>
#include <QCache>
#include <QHash>
#include <QVariant>
#include <QSharedPointer>
#include <QScriptEngine>
#include "element.h"
#include "context.h"

class QXmlStreamReader;
class Window;

/**
 * @brief Load ui script
 */
class QLUISHARED_EXPORT Loader : public QObject
{
    Q_OBJECT
public:
    explicit Loader(QObject *parent = 0);


    static Loader &globalLoader();
    /*********************************************************************
     *                          Load
     * *******************************************************************/
public:
    Element* loadXML(QFile &file);
    Element* loadXML(const QString& path);
    Element* loadXML(QXmlStreamReader &root, const QString& path=0);

    Window *loadXMLFromIndex(const QString& name);

protected:

    bool loadImport(QXmlStreamReader &reader, Context *context, const QString& path);
    bool loadInclude(QXmlStreamReader &root, Context *context, const QString& path);
    Element* loadWindow(QXmlStreamReader &reader, Context *context, const QString& path);
    bool loadCode(QXmlStreamReader &reader, Context *context, const QString& path);
    bool loadIndex(QXmlStreamReader &reader, Context *context, const QString& path);
    /**
     * @brief loadElement
     * @param reader
     * @param context
     * @return
     */
    Element* loadElement(QXmlStreamReader &reader, Context *context, const QString &path);
    Element* createElement(const QString &type, const Context *context) const;

private:
    QHash<QString, QString> index_name_path_;
    QHash<quint32, QString> index_id_path_;

    /*********************************************************************
     *                          Cache
     * *******************************************************************/
public:
    bool hasCached(const QString &path) const;
    bool hasCached(QFile &file) const;
    Element* getCacheCopy(QFile &file);
    Element* getCacheCopy(const QString &path);

    void cache(const QString &path, const Element &e);
    void cache(QFile &file, const Element &e);

private:
    QCache<QString, Element> element_cache_;    // path->Element


    /*********************************************************************
     *                          Script
     * *******************************************************************/
public:

private:
    QScriptEngine script_engine_;
};

#endif // LOADER_H
